#include "AP_Cluster.h"
#include <stdio.h>
#include <iostream.h>
#include <mpi.h>
#include <stdlib.h>
#include <string.h>
//---------------------------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------------------------
AP_Cluster::AP_Cluster() :dataPoints(NULL), numberDataPoints(0), preferencePoint(NULL), idx(NULL), numberCluster(0), maxits(1000),
                          convits(100), dampfact(0.5), noise(false), cicle(0) {}
//---------------------------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------------------------
AP_Cluster::AP_Cluster(const AP_Cluster *AP_Cluster_tmp) :cicle(0) {

  numberDataPoints 	= AP_Cluster_tmp->numberDataPoints;
  numberCluster 		= AP_Cluster_tmp->numberCluster;

  if (dataPoints) delete[] dataPoints;
  dataPoints = new Sim_Cluster[numberDataPoints];
  for (int i = 0; i < numberDataPoints; i++) dataPoints[i] = AP_Cluster_tmp->dataPoints[i];

  if (preferencePoint) delete[] preferencePoint;
  preferencePoint = new double[numberDataPoints];
  for (int i = 0; i < numberDataPoints; i++) preferencePoint[i] = AP_Cluster_tmp->preferencePoint[i];

  if (idx) delete[] idx;
  idx = new int[numberDataPoints];
  for (int i = 0; i < numberDataPoints; i++) idx[i] = AP_Cluster_tmp->idx[i];

  maxits    = AP_Cluster_tmp->maxits;
  convits   = AP_Cluster_tmp->convits;
  dampfact  = AP_Cluster_tmp->dampfact;
  noise     = AP_Cluster_tmp->noise;

}
//---------------------------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------------------------
AP_Cluster::~AP_Cluster() { 

  if (dataPoints)	delete[] dataPoints;
  if (preferencePoint) 	delete[] preferencePoint;
  if (idx)		delete[] idx;

}
//---------------------------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------------------------
void AP_Cluster::DataPoints(Sim_Cluster *Sim_Cluster_tmp, int size) {

  numberDataPoints 	= size;

  if (dataPoints) delete[] dataPoints;
  dataPoints = new Sim_Cluster[numberDataPoints];
  for (int i = 0; i < numberDataPoints; i++) dataPoints[i] = Sim_Cluster_tmp[i];

}
//---------------------------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------------------------
void AP_Cluster::NumberDataPoints(int numberDataPoints_tmp) {

  numberDataPoints = numberDataPoints_tmp;

}
//---------------------------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------------------------
void AP_Cluster::PreferencePoint(double *preferencePoint_tmp, int size) {

  numberDataPoints 	= size;

  if (preferencePoint) delete[] preferencePoint;
  preferencePoint = new double[numberDataPoints];
  for (int i = 0; i < numberDataPoints; i++) preferencePoint[i] = preferencePoint_tmp[i];

}
//---------------------------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------------------------
void AP_Cluster::OnePreference(bool onePreference_tmp) {

  onePreference = onePreference_tmp;

}
//---------------------------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------------------------
void AP_Cluster::Idx(int *idx_tmp, int size) {

  numberDataPoints 	= size;

  if (idx) delete[] idx;
  idx = new int[numberDataPoints];
  for (int i = 0; i < numberDataPoints; i++) idx[i] = idx_tmp[i];

}
//---------------------------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------------------------
void AP_Cluster::NumberCluster(int numberCluster_tmp) {

  numberCluster = numberCluster_tmp;

}
//---------------------------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------------------------
void AP_Cluster::Maxits(int maxits_tmp) {

  maxits = maxits_tmp;

}
//---------------------------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------------------------
void AP_Cluster::Convits(int convits_tmp) {

  convits = convits_tmp;

}
//---------------------------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------------------------
void AP_Cluster::Dampfact(double dampfact_tmp) {

  dampfact  = dampfact_tmp;

}
//---------------------------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------------------------
void AP_Cluster::Noise(bool noise_tmp) {

  noise	= noise_tmp;

}
//---------------------------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------------------------
Sim_Cluster* AP_Cluster::DataPoints(int position) {

  if (position > numberDataPoints) return NULL;
  return dataPoints[position];

}
//---------------------------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------------------------
int AP_Cluster::NumberDataPoints(void) {

  return numberDataPoints;

}
//---------------------------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------------------------
void AP_Cluster::PreferencePoint(int position) {

  if (position > numberDataPoints) return NULL;
  return preferencePoint[position];

}
//---------------------------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------------------------
bool AP_Cluster::OnePreference(void) {

  return onePreference;

}
//---------------------------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------------------------
int AP_Cluster::Idx(int position) {

  if (position > numberDataPoints) return NULL;
  return idx[position];

}
//---------------------------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------------------------
int AP_Cluster::NumberCluster(void) {

  return numberCluster;

}
//---------------------------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------------------------
int AP_Cluster::Maxits(void) {

  return maxits;

}
//---------------------------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------------------------
int AP_Cluster::Convits(void) {

  return convits;

}
//---------------------------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------------------------
double AP_Cluster::Dampfact(void) {

  return dampfact;

}
//---------------------------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------------------------
bool AP_Cluster::Noise(void) {

  return noise;

}
//---------------------------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------------------------
void AP_Cluster::ComputeAP_Cluster(int block) {

    char commandLine[1000];
    CreateSimilarityFile();

    char simMatrix[100];
    sprintf(simMatrix, "./apcluster SimilarityMatrixN%d_AP%7d.txt ", block, cicle);
    strcpy(commandLine, simMatrix);

    if (!OnePreference) {
        CreatePreferenceFile();
        char prefMatrix[100];
        sprintf(prefMatrix, "PreferenceN%d_AP%7d.txt ", block, cicle);
        strcat(commandLine, prefMatrix);
    }
    else {
        char prefMatrix[100];
        sprintf(prefMatrix, "%f", *(preferencePoint));
        strcat(commandLine, prefMatrix);
    }

    char outIDX[100];
    sprintf(outIDX, "IDXResultN%d");

    strcat(commandLine, "\0");
    
    system(commandLine);

    cicle++;

}
//---------------------------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------------------------
